package com.blast.manager.presenter

import android.text.TextUtils
import com.wxl.common.AppConstant
import com.wxl.common.AppContext
import com.wxl.common.bean.ScanLeiGuanBean
import com.wxl.common.room.entity.LeiGuanEntity
import com.wxl.common.room.entity.LogEntity
import com.wxl.common.serialport.*
import com.wxl.common.util.Toll
import com.wxl.common.viewmodel.AbsPresenter


/**
 * 扫描控制板雷管信息
 */
class ScanOnlineLGPresenter : AbsPresenter() {

    interface OnScanOnlineLGCallback {
        fun onScanOnlineResult(lgs: ArrayList<LeiGuanEntity>,isNotMatch:Boolean)
        fun onScanNotMatchResult(isNeedDelay:Boolean,isNotMatch:Boolean,state:Int,lgs: ArrayList<LeiGuanEntity>)
        fun onScanOnlineProgress(title:String,p: Int, total: Int)
        fun onScanChargeChanged(mVoltage: Int, mElectric: Int)
        fun onScanOnlineFailed(e: String)
    }

    var scanProgress = 0
    var mCurrentDetonatorNum = 0
    var mDetonatorTotalNum = 1
    var mDetonatorMaxNumLimit = 0
    var mOnScanOnlineLGCallback: OnScanOnlineLGCallback? = null
    val lgs = arrayListOf<LeiGuanEntity>()
    private var isNeedDelay = false
    private var isNotMatch = false
    private var state:Int=0

    override fun onCreated(vararg args: Any) {

    }


    fun start(isNeedInputDelay:Boolean,mOnScanOnlineLGCallback: OnScanOnlineLGCallback) {
       // this.isNeedDelay = isNeedInputDelay
        mDetonatorMaxNumLimit = AppContext.appContext.getLeiGuanMaxNum()
        lgs.clear()
        this.mOnScanOnlineLGCallback = mOnScanOnlineLGCallback
        onScanControlData()
//        Serials.registerSingleStartHexSerial(CmdCode.KZB_CLEAR_STATE_OK_ASK, object : Serial() {
//            override fun loadReceiveData(data: String) {
//                onScanControlData()
//            }
//        })
//        Serials.registerSingleStartHexSerial(CmdCode.KZB_CLEAR_STATE_E_ASK, object : Serial() {
//            override fun loadReceiveData(data: String) {
//                mOnScanOnlineLGCallback.onScanOnlineFailed(checkErrorCode(-100))
//            }
//        })
//        SerialPortManager.send(CmdCode.KZB_CLEAR_STATE_CMD)
    }


    /**
     * 清除控制板数据成功, 扫描控制板雷管信息
     */
    private fun onScanControlData() {
        mOnScanOnlineLGCallback?.onScanOnlineProgress("正在扫描控制板信息...",0, 101)
        Serials.registerSingleStartHexSerial(CmdCode.KZB_SCAN_LG_OK_ASK, object : Serial() {
            override fun loadReceiveData(data: String) {
                scanProgress = 0
                LogEntity.addLog("在线扫描","在线扫描","扫描雷管信息")
                onQueryControlLgData()
            }
        })
        Serials.registerSingleStartHexSerial(CmdCode.KZB_SCAN_LG_E_ASK, object : Serial() {
            override fun loadReceiveData(data: String) {
                mOnScanOnlineLGCallback?.onScanOnlineFailed("扫描控制板信息错误！")
            }
        })
        //发送扫描指令
        SerialPortManager.send(CmdCode.KZB_SCAN_LG_CMD)
    }


    /**
     * 查询控制板雷管信息
     */
    private fun onQueryControlLgData() {
        Serials.registerSingleStartHexSerial(CmdCode.KZB_QUERY_LG_INFO_OK_ASK, object : Serial() {
            override fun loadReceiveData(data: String) {
                onParseScanControlData(data)
            }
        })
        SerialPortManager.send(CmdCode.KZB_QUERY_LG_INFO_CMD)
    }

    /**
     * 解析扫描出来的数据
     */
    @Synchronized
    private fun onParseScanControlData(data: String) {
        if (data.length > 30) {
            val result = ScanLeiGuanBean.parse(data)
            if(TextUtils.equals("06",result.state)){
                //isNeedDelay = true
                state = 6
            }

            if(TextUtils.equals("07",result.state) || TextUtils.equals("05",result.state)){
                isNotMatch = true
                state = result.state.toInt()
            }

            mOnScanOnlineLGCallback?.onScanChargeChanged(result.mVoltage,result.mElectric)


            //stateCode 在线雷管扫描状态 0 正常，1 上电失败，2 电流异常， 3 雷管数据已满， 4 未扫描到雷管，数量数量为0， 5 通信电压异常
            scanProgress++
            mOnScanOnlineLGCallback?.onScanOnlineProgress(if(AppConstant.isTest)"正在扫描控制板信息...($scanProgress)" else "正在扫描控制板信息...",if(result.progress < 100) result.progress else 99, 102)
            if (result.progress < 100) {
                if (result.stateCode == 0) {
                    onQueryControlLgData()
                } else {
                    mOnScanOnlineLGCallback?.onScanOnlineFailed(checkErrorCode(result.stateCode))
                }
            } else {
                if (result.stateCode == 0) {
                    mCurrentDetonatorNum = 0
                    LogEntity.addLog("在线扫描","在线扫描","读取控制器信息")
                    onReadControlData()
                } else {
                    mOnScanOnlineLGCallback?.onScanOnlineFailed(checkErrorCode(result.stateCode))
                }
            }
        } else {
            mOnScanOnlineLGCallback?.onScanOnlineFailed(checkErrorCode(-300))
        }

    }


    /**
     * 扫描完成，读取控制板雷管数据
     */
    @Synchronized
    private fun onReadControlData() {
        val p =  (((mCurrentDetonatorNum.toFloat() / mDetonatorTotalNum.toFloat()) / 2) * 10).toInt()
        mOnScanOnlineLGCallback?.onScanOnlineProgress("正在读取控制板信息...",if(p < 100) p else 98, 101)
        val number = SerialUtil.getCurrentDetonatorNum(mCurrentDetonatorNum)
        Serials.registerSingleStartHexSerial(CmdCode.KZB_READ_LG_INFO_ASK, object : Serial() {
            override fun loadReceiveData(data: String) {
                if (data.length > 40) {
                    onParesReadControlData(data)
                } else {
                    mOnScanOnlineLGCallback?.onScanOnlineFailed(checkErrorCode(-200))
                }
            }
        })
        SerialPortManager.send(CmdCode.KZB_READ_LG_INFO_CMD + number)
    }

    /**
     * 解析控制雷管信息
     */
    private fun onParesReadControlData(data: String) {
        val model = LeiGuanEntity.parse(data)
        mDetonatorTotalNum = model.total
        lgs.add(model)
        checkSendReadNextData()
    }


    /**
     * 检查是否已经到达组网限制
     */
    private fun checkSendReadNextData() {
        if (mCurrentDetonatorNum + 1 >= mDetonatorMaxNumLimit) {
            Toll.toll("已达到最大组网数")
            if(isNeedDelay){
                //sendDelay()
            } else {
                mOnScanOnlineLGCallback?.onScanOnlineResult(lgs,isNotMatch)
            }
            mOnScanOnlineLGCallback?.onScanNotMatchResult(isNeedDelay,isNotMatch,state,lgs)
            return
        }
        if (mDetonatorTotalNum <= mCurrentDetonatorNum + 1) {
            if(isNeedDelay){
                //sendDelay()
            } else {
                mOnScanOnlineLGCallback?.onScanOnlineResult(lgs,isNotMatch)
            }
            mOnScanOnlineLGCallback?.onScanNotMatchResult(isNeedDelay,isNotMatch,state,lgs)
        } else {
            mCurrentDetonatorNum++
            onReadControlData()
        }
    }




    /**
     * 错误信息
     */
    fun checkErrorCode(stateCode: Int): String {
        var str = ""
        if (1 == stateCode) {
            str = "起爆器上电失败！"
        } else if (2 == stateCode) {
            str = "起爆器通信电压异常！"
        } else if (3 == stateCode) {
            str = "起爆器上电电流异常！"
        } else if (4 == stateCode) {
            str = "起爆器输出短路！"
        } else if (5 == stateCode) {
            str = "雷管复位后电流异常！"
        } else if (6 == stateCode) {
            str = "第1组低压充电电流异常！"
        } else if (7 == stateCode) {
            str = "第2组低压充电电流异常！"
        } else if (8 == stateCode) {
            str = "第3组低压充电电流异常！"
        } else if (9 == stateCode) {
            str = "第4组低压充电电流异常！"
        } else if (10 == stateCode) {
            str = "第5组低压充电电流异常！"
        } else if (11 == stateCode) {
            str = "第6组低压充电电流异常！"
        } else if (12 == stateCode) {
            str = "充电高压升压失败！"
        } else if (13 == stateCode) {
            str = "充电高压充电电流异常！"
        } else if (14 == stateCode) {
            str = "充电低压降压失败！"
        } else if (15 == stateCode) {
            str = "充电低压降压电流异常！"
        } else if (16 == stateCode) {
            str = "充电还原高压失败！"
        } else if (17 == stateCode) {
            str = "充电还原高压充电电流异常！"
        } else if (18 == stateCode) {
            str = "起爆低压降压失败！"
        } else if (19 == stateCode) {
            str = "起爆低压降压电流异常！"
        } else if (20 == stateCode) {
            str = "电流异常, 可能造成拒爆！"
        } else if (21 == stateCode) {
            str = "电流严重异常, 可能造成大规模拒爆, 禁止起爆！"
        } else if (100 == stateCode) {
            str = "雷管状态异常 (有雷管未分配到短地址，状态字第0bit位有反馈)！"
        }
        if (101 == stateCode) {
            str = "未检测到雷管，雷管数量为0！"
        } else if (102 == stateCode) {
            str = "雷管数据已满，数量超出范围, 请检查雷管数量！"
        } else if (103 == stateCode) {
            str = "雷管数量和方案不一致！"
        } else if (104 == stateCode) {
            str = "雷管连接异常！"
        } else if (105 == stateCode) {
            str = "雷管延时设置超出范围！"
        } else if (106 == stateCode) {
            str = "雷管密码验证出错！"
        } else if (107 == stateCode) {
            str = "雷管时间校准出错！"
        } else if (108 == stateCode) {
            str = "雷管写延时出错！"
        } else if (109 == stateCode) {
            str = "雷管写延时出错+雷管时间校准出错！"
        } else if (110 == stateCode) {
            str = "雷管放电使能标志异常！"
        } else if (111 == stateCode) {
            str = "雷管充电标志异常！"
        } else if (112 == stateCode) {
            str = "起爆状态错误，终止起爆！"
        } else if (113 == stateCode) {
            str = "起爆时间超时，终止起爆，雷管已充入高压, 30分钟内禁止进入爆破现场！"
        } else if(-200 == stateCode){
            str = "读取控制板信息返回错误！"
        }else if(-300 == stateCode){
            str = "扫描控制板信息返回错误！"
        }else if(-100 == stateCode){
            str = "清除控制板信息返回失败！"
        }else if(-101 == stateCode){
            str = "延时下传失败！"
        }
        return str
    }


    override fun onDestroy() {
        super.onDestroy()
        Serials.unRegisterSingleStartHexSerial(CmdCode.KZB_READ_LG_INFO_ASK)
        Serials.unRegisterSingleStartHexSerial(CmdCode.KZB_QUERY_LG_INFO_OK_ASK)
        Serials.unRegisterSingleStartHexSerial(CmdCode.KZB_SCAN_LG_OK_ASK)
        Serials.unRegisterSingleStartHexSerial(CmdCode.KZB_SCAN_LG_E_ASK)
        Serials.unRegisterSingleStartHexSerial(CmdCode.KZB_CLEAR_STATE_OK_ASK)
        Serials.unRegisterSingleStartHexSerial(CmdCode.KZB_CLEAR_STATE_E_ASK)
        Serials.unRegisterSingleStartHexSerial(CmdCode.DELAY_INPUT_OK_ASK)
        Serials.unRegisterSingleStartHexSerial(CmdCode.DELAY_INPUT_E_ASK)
    }
}